const IsEqual = require('../template')

console.log("=== IsEqual 基础测试 ===")

// 测试基本类型相等性比较
console.log(
  "基本类型相等性比较:", (() => {
    return IsEqual.isEqual(42, 42) === true &&
      IsEqual.isEqual('hello', 'hello') === true &&
      IsEqual.isEqual(true, true) === true &&
      IsEqual.isEqual(null, null) === true &&
      IsEqual.isEqual(undefined, undefined) === true &&
      IsEqual.isEqual(42, '42') === false &&
      IsEqual.isEqual('hello', 'world') === false &&
      IsEqual.isEqual(true, false) === false &&
      IsEqual.isEqual(null, undefined) === false
  })()
)

// 测试数组相等性比较
console.log(
  "数组相等性比较:", (() => {
    const arr1 = [1, 2, 3]
    const arr2 = [1, 2, 3]
    const arr3 = [1, 2, 4]
    const arr4 = [1, 2]

    return IsEqual.isEqual(arr1, arr2) === true &&
      IsEqual.isEqual(arr1, arr3) === false &&
      IsEqual.isEqual(arr1, arr4) === false &&
      IsEqual.isEqual([], []) === true &&
      IsEqual.isEqual([1], [1]) === true &&
      IsEqual.isEqual([1], ['1']) === false
  })()
)

// 测试对象相等性比较
console.log(
  "对象相等性比较:", (() => {
    const obj1 = { a: 1, b: 2 }
    const obj2 = { a: 1, b: 2 }
    const obj3 = { a: 1, b: 3 }
    const obj4 = { a: 1 }

    return IsEqual.isEqual(obj1, obj2) === true &&
      IsEqual.isEqual(obj1, obj3) === false &&
      IsEqual.isEqual(obj1, obj4) === false &&
      IsEqual.isEqual({}, {}) === true &&
      IsEqual.isEqual({ a: 1 }, { a: 1 }) === true &&
      IsEqual.isEqual({ a: 1 }, { a: '1' }) === false
  })()
)

// 测试嵌套对象相等性比较
console.log(
  "嵌套对象相等性比较:", (() => {
    const obj1 = { a: { b: { c: 42 } } }
    const obj2 = { a: { b: { c: 42 } } }
    const obj3 = { a: { b: { c: 43 } } }

    return IsEqual.isEqual(obj1, obj2) === true &&
      IsEqual.isEqual(obj1, obj3) === false &&
      IsEqual.isEqual(obj1.a, obj2.a) === true &&
      IsEqual.isEqual(obj1.a.b, obj2.a.b) === true
  })()
)

// 测试数组对象混合相等性比较
console.log(
  "数组对象混合相等性比较:", (() => {
    const obj1 = {
      users: [
        { id: 1, name: 'Alice' },
        { id: 2, name: 'Bob' }
      ],
      meta: { count: 2 }
    }
    const obj2 = {
      users: [
        { id: 1, name: 'Alice' },
        { id: 2, name: 'Bob' }
      ],
      meta: { count: 2 }
    }
    const obj3 = {
      users: [
        { id: 1, name: 'Alice' },
        { id: 2, name: 'Charlie' }
      ],
      meta: { count: 2 }
    }

    return IsEqual.isEqual(obj1, obj2) === true &&
      IsEqual.isEqual(obj1, obj3) === false &&
      IsEqual.isEqual(obj1.users, obj2.users) === true &&
      IsEqual.isEqual(obj1.meta, obj2.meta) === true
  })()
)

// 测试日期对象相等性比较
console.log(
  "日期对象相等性比较:", (() => {
    const date1 = new Date('2023-01-01')
    const date2 = new Date('2023-01-01')
    const date3 = new Date('2023-01-02')

    return IsEqual.isEqual(date1, date2) === true &&
      IsEqual.isEqual(date1, date3) === false &&
      IsEqual.isEqual(date1, '2023-01-01') === false
  })()
)

// 测试正则表达式相等性比较
console.log(
  "正则表达式相等性比较:", (() => {
    const regex1 = /test/gi
    const regex2 = /test/gi
    const regex3 = /test/g
    const regex4 = /test/i

    return IsEqual.isEqual(regex1, regex2) === true &&
      IsEqual.isEqual(regex1, regex3) === false &&
      IsEqual.isEqual(regex1, regex4) === false &&
      IsEqual.isEqual(regex1, 'test') === false
  })()
)

// 测试函数相等性比较
console.log(
  "函数相等性比较:", (() => {
    const func1 = function test() { return 'hello' }
    const func2 = function test() { return 'hello' }
    const func3 = function test() { return 'world' }

    return IsEqual.isEqual(func1, func2) === false && // 函数引用不同
      IsEqual.isEqual(func1, func3) === false &&
      IsEqual.isEqual(func1, 'hello') === false
  })()
)

// 测试空值相等性比较
console.log(
  "空值相等性比较:", (() => {
    return IsEqual.isEqual(null, null) === true &&
      IsEqual.isEqual(undefined, undefined) === true &&
      IsEqual.isEqual(null, undefined) === false &&
      IsEqual.isEqual(null, 0) === false &&
      IsEqual.isEqual(null, '') === false &&
      IsEqual.isEqual(undefined, 0) === false &&
      IsEqual.isEqual(undefined, '') === false
  })()
)

// 测试Symbol相等性比较
console.log(
  "Symbol相等性比较:", (() => {
    const sym1 = Symbol('test')
    const sym2 = Symbol('test')
    const sym3 = sym1

    return IsEqual.isEqual(sym1, sym2) === false && // 不同的Symbol
      IsEqual.isEqual(sym1, sym3) === true &&  // 相同的Symbol
      IsEqual.isEqual(sym1, 'test') === false
  })()
)

// 测试BigInt相等性比较
console.log(
  "BigInt相等性比较:", (() => {
    const big1 = BigInt(123)
    const big2 = BigInt(123)
    const big3 = BigInt(124)

    return IsEqual.isEqual(big1, big2) === true &&
      IsEqual.isEqual(big1, big3) === false &&
      IsEqual.isEqual(big1, 123) === false &&
      IsEqual.isEqual(big1, '123') === false
  })()
)

// 测试Map相等性比较
console.log(
  "Map相等性比较:", (() => {
    const map1 = new Map([['a', 1], ['b', 2]])
    const map2 = new Map([['a', 1], ['b', 2]])
    const map3 = new Map([['a', 1], ['b', 3]])

    return IsEqual.isEqual(map1, map2) === true &&
      IsEqual.isEqual(map1, map3) === false &&
      IsEqual.isEqual(map1, {}) === false
  })()
)

// 测试Set相等性比较
console.log(
  "Set相等性比较:", (() => {
    const set1 = new Set([1, 2, 3])
    const set2 = new Set([1, 2, 3])
    const set3 = new Set([1, 2, 4])

    return IsEqual.isEqual(set1, set2) === true &&
      IsEqual.isEqual(set1, set3) === false &&
      IsEqual.isEqual(set1, []) === false
  })()
)

// 测试循环引用相等性比较
console.log(
  "循环引用相等性比较:", (() => {
    const obj1 = { a: 1 }
    obj1.self = obj1

    const obj2 = { a: 1 }
    obj2.self = obj2

    try {
      return IsEqual.isEqual(obj1, obj2) === true
    } catch (error) {
      return true // 循环引用应该正确处理
    }
  })()
)

// 测试原型链相等性比较
console.log(
  "原型链相等性比较:", (() => {
    function TestClass() {
      this.value = 'test'
    }
    TestClass.prototype.method = function() { return 'method' }

    const instance1 = new TestClass()
    const instance2 = new TestClass()

    return IsEqual.isEqual(instance1, instance2) === true &&
      IsEqual.isEqual(instance1.value, instance2.value) === true
  })()
)

// 测试undefined属性相等性比较
console.log(
  "undefined属性相等性比较:", (() => {
    const obj1 = { a: 1, b: undefined, c: 3 }
    const obj2 = { a: 1, b: undefined, c: 3 }
    const obj3 = { a: 1, c: 3 }

    return IsEqual.isEqual(obj1, obj2) === true &&
      IsEqual.isEqual(obj1, obj3) === false
  })()
)

// 测试null属性相等性比较
console.log(
  "null属性相等性比较:", (() => {
    const obj1 = { a: 1, b: null, c: 3 }
    const obj2 = { a: 1, b: null, c: 3 }
    const obj3 = { a: 1, b: undefined, c: 3 }

    return IsEqual.isEqual(obj1, obj2) === true &&
      IsEqual.isEqual(obj1, obj3) === false
  })()
)

// 测试复杂嵌套结构相等性比较
console.log(
  "复杂嵌套结构相等性比较:", (() => {
    const obj1 = {
      arr: [1, { nested: 2 }, [3, 4]],
      obj: {
        deep: {
          value: 'test',
          arr: [5, 6]
        }
      },
      primitives: {
        str: 'string',
        num: 42,
        bool: true
      }
    }
    const obj2 = {
      arr: [1, { nested: 2 }, [3, 4]],
      obj: {
        deep: {
          value: 'test',
          arr: [5, 6]
        }
      },
      primitives: {
        str: 'string',
        num: 42,
        bool: true
      }
    }
    const obj3 = {
      arr: [1, { nested: 2 }, [3, 4]],
      obj: {
        deep: {
          value: 'test',
          arr: [5, 7] // 不同的值
        }
      },
      primitives: {
        str: 'string',
        num: 42,
        bool: true
      }
    }

    return IsEqual.isEqual(obj1, obj2) === true &&
      IsEqual.isEqual(obj1, obj3) === false
  })()
)

// 测试不同长度数组相等性比较
console.log(
  "不同长度数组相等性比较:", (() => {
    const arr1 = [1, 2, 3]
    const arr2 = [1, 2, 3, 4]
    const arr3 = [1, 2]

    return IsEqual.isEqual(arr1, arr2) === false &&
      IsEqual.isEqual(arr1, arr3) === false &&
      IsEqual.isEqual(arr2, arr3) === false
  })()
)

// 测试不同属性数量对象相等性比较
console.log(
  "不同属性数量对象相等性比较:", (() => {
    const obj1 = { a: 1, b: 2 }
    const obj2 = { a: 1, b: 2, c: 3 }
    const obj3 = { a: 1 }

    return IsEqual.isEqual(obj1, obj2) === false &&
      IsEqual.isEqual(obj1, obj3) === false &&
      IsEqual.isEqual(obj2, obj3) === false
  })()
)

// 测试类型转换相等性比较
console.log(
  "类型转换相等性比较:", (() => {
    return IsEqual.isEqual(1, '1') === false &&
      IsEqual.isEqual(true, 1) === false &&
      IsEqual.isEqual(false, 0) === false &&
      IsEqual.isEqual(null, 0) === false &&
      IsEqual.isEqual(undefined, null) === false
  })()
)

// 测试边界情况相等性比较
console.log(
  "边界情况相等性比较:", (() => {
    return IsEqual.isEqual(0, -0) === true &&
      IsEqual.isEqual(NaN, NaN) === true &&
      IsEqual.isEqual(Infinity, Infinity) === true &&
      IsEqual.isEqual(-Infinity, -Infinity) === true &&
      IsEqual.isEqual(Infinity, -Infinity) === false
  })()
)

console.log("=== IsEqual 基础测试完成 ===")
